package com.wkbb.basic.controller.open;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.wkbb.basic.config.BasicConfig;
import com.wkbb.basic.feign.WxFeignService;
import com.wkbb.basic.model.*;
import com.wkbb.basic.service.*;
import com.wkbb.basic.thread.ClearNickNameTask;
import com.wkbb.common.config.ServiceConfig;
import com.wkbb.common.constants.*;
import com.wkbb.common.dto.ResultDTO;
import com.wkbb.common.dto.basic.*;
import com.wkbb.common.dto.common.RedisPropDto;
import com.wkbb.common.dto.im.ImUserDto;
import com.wkbb.common.dto.wx.AccountDto;
import com.wkbb.common.dto.wx.AccountInfoDto;
import com.wkbb.common.dto.wx.UserOpenDto;
import com.wkbb.common.dto.wx.WechatKfMessageDto;
import com.wkbb.common.enums.*;
import com.wkbb.common.redis.RedisTemplateUtil;
import com.wkbb.common.utils.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 基础模块对外接口
 */
@RestController
@Api(description = "用户模块对外接口")
@RequestMapping("/basic/{apiVersion}/open")
@Slf4j
public class UserController {

    @Autowired
    private ServiceConfig serviceConfig;

    @Autowired
    private BasicConfig basicConfig;

    @Autowired
    private UserService userService;

    @Autowired
    private UserOpenService userOpenService;

    @Autowired
    private TeacherManageService teacherManageService;

    @Autowired
    private StudentService studentService;

    @Autowired
    private FamilyService familyService;

    @Autowired
    private RedisTemplateUtil redisTemplateUtil;

    @Autowired
    private WxFeignService wxFeignService;

    @Autowired
    private EmployeeService employeeService;

    @Autowired
    private UserFaceService userFaceService;

    @ApiOperation(value = "修改手机号")
    @RequestMapping(value = "/changeMobile", method = RequestMethod.POST)
    public ResultDTO<?> changeMobile(
            @ApiParam(value = "接口版本", defaultValue = VersionConstant.V1, required = true) @PathVariable(name = "apiVersion") String apiVersion,
            @Valid @RequestBody UserDto userDto) {
        try {
            return userOpenService.changeMobile(userDto);
        } catch (Exception e) {
            log.error("***********TeacherManageController.getTeacherInfoPageList******", e);
            return new ResultDTO<>(false);
        }
    }

    @ApiOperation(value = "查询老师班级列表")
    @RequestMapping(value = "/getEmloyeeByPwd", method = RequestMethod.GET)
    public ResultDTO<EmployeeInfoDto> getEmloyeeByPwd(
            @ApiParam(value = "接口版本", defaultValue = VersionConstant.V1, required = true) @PathVariable(name = "apiVersion") String apiVersion,
            @ApiParam(value = "账号", required = true) @RequestParam(name = "account", required = true) String account,
            @ApiParam(value = "密码", required = true) @RequestParam(name = "password", required = true) String password
    ) {
        try {
            return new ResultDTO<>(userService.getEmloyeeByPwd(account,password));
        } catch (Exception e) {
            log.error("***********TeacherManageController.getTeacherInfoPageList******", e);
            return new ResultDTO<>(false);
        }
    }

    @ApiOperation(value = "查询老师班级列表")
    @RequestMapping(value = "/getTeacherClassList", method = RequestMethod.GET)
    public ResultDTO<List<ClassInfoDto>> getTeacherClassList(
            @ApiParam(value = "接口版本", defaultValue = VersionConstant.V1, required = true) @PathVariable(name = "apiVersion") String apiVersion,
            @ApiParam(value = "机构id", required = true) @RequestParam(name = "orgId", required = true) Long orgId,
            @ApiParam(value = "老师id", required = true) @RequestParam(name = "userId", required = true) Long userId
    ) {
        if (null == orgId || userId == null) {
            return new ResultDTO<>(ErrorCode.PARAM_MISSING);
        }
        try {
            List<ClassInfoDto> classList = userOpenService.getClassListByUser(orgId, userId, 1);
            return new ResultDTO<>(classList);
        } catch (Exception e) {
            log.error("***********TeacherManageController.getTeacherInfoPageList******", e);
            return new ResultDTO<>(false);
        }
    }

    @ApiOperation(value = "查询学校学生列表")
    @RequestMapping(value = "/getStudentList", method = RequestMethod.GET)
    public ResultDTO<List<StudentInfoDto>> getStudentList(
            @ApiParam(value = "接口版本", defaultValue = VersionConstant.V1, required = true) @PathVariable(name = "apiVersion") String apiVersion,
            @ApiParam(value = "机构id", required = false) @RequestParam(name = "orgId", required = false) Long orgId,
            @ApiParam(value = "班级id", required = false) @RequestParam(name = "classId", required = false) Long classId
    ) {
        if (null == orgId && classId == null) {
            return new ResultDTO<>(ErrorCode.PARAM_MISSING);
        }
        try {
            List<StudentInfoDto> classList = userOpenService.getStudentInfoByOrg(orgId,classId);
            return new ResultDTO<>(classList);
        } catch (Exception e) {
            log.error("***********TeacherManageController.getTeacherInfoPageList******", e);
            return new ResultDTO<>(false);
        }
    }

    @ApiOperation(value = "操作用户并返回用户信息")
    @RequestMapping(value = "/doUserByOpen", method = RequestMethod.POST)
    public ResultDTO<UserDto> doUserByOpen(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "登录类型(1公众号 2小程序 3企业微信)", required = true) @RequestParam(name = "loginType", required = true) Integer loginType,
            @ApiParam(value = "是否强制刷新", required = false, defaultValue = "false") @RequestParam(name = "forceRefresh", required = false) Boolean forceRefresh,
            @ApiParam(value = "是否路由模式", required = false, defaultValue = "false") @RequestParam(name = "routeFlag", required = false) Boolean routeFlag,
            @ApiParam(value = "小程序(0微看 1访客 2体育)", required = false, defaultValue = "0") @RequestParam(name = "miniApp", required = false) Integer miniApp,
            @RequestBody UserDto userDto) {

        log.info("***********doUserByOpen******userDto:{},loginType:{},forceRefresh:{} routeFlag:{} miniApp:{}", JSONObject.toJSON(userDto).toString(),loginType,forceRefresh,routeFlag,miniApp);

        try {

            Long accountId = userDto.getAccountId();
            String unionId = userDto.getUnionId();
//            if (null == accountId || StringUtil.isEmptyIgnoreBlank(unionId)) {
//                return new ResultDTO(ErrorCode.PARAM_MISSING);
//            }
//            //默认微看小程序
//            if(loginType==LoginTypeEnum.MINI.getValue().shortValue() && null==miniApp)
//            {
//                miniApp = MiniAppEnum.MAIN_MINI_APP.getCode();
//            }
//            //默认非路由模式
//            if(null==routeFlag)
//            {
//                routeFlag = false;
//            }
//            //云想小程序登录的，转换账户（后面再删除此逻辑）
//            if(accountId.equals(136))
//            {
//                accountId = basicConfig.getDefaultCpAccountId();
//            }

            UserDto user = null;
            Boolean doLoginFlag = true;//是否需要重新登录
//            String tokenRedisKey = null;
//            String userTokenRedisKey = null;
//
//            //缓存KEY
//            if(routeFlag) {
//                tokenRedisKey = RedisKeyConstant.WKBB_BASIC_USER_ROUTE + RedisKeyConstant.WKBB_BASIC_USER_ROUTE_TOKEN_UNIONID;//路由模式
//                userTokenRedisKey = String.format(tokenRedisKey, unionId);
//            }
//            else
//            {
//                tokenRedisKey = RedisKeyConstant.WKBB_BASIC_USER_FRONT + RedisKeyConstant.WKBB_BASIC_USER_FRONT_ACCOUNT_UNIONID;//绑定公众号模式
//                userTokenRedisKey = String.format(tokenRedisKey, accountId, unionId);
//            }

            //非强制刷新，取缓存数据
//            if (!forceRefresh) {
//                String userJsonStr = redisTemplateUtil.getJSON(userTokenRedisKey);
//                log.info("userJsonStr:{}",userJsonStr);
//                //从微信进入企微的家长，第二次获取
//                if (StringUtil.isEmpty(userJsonStr) && loginType == LoginTypeEnum.MINI.getValue().shortValue() && basicConfig.getDefaultAccountId().equals(accountId)) {
//                    String cpUserTokenRedisKey = null;
//                    if(routeFlag) {
//                        cpUserTokenRedisKey = String.format(tokenRedisKey, unionId);//路由模式
//                    }
//                    else
//                    {
//                        cpUserTokenRedisKey = String.format(tokenRedisKey, basicConfig.getDefaultCpAccountId(), unionId);//绑定公众号模式
//                    }
//                    log.info("cpUserTokenRedisKey:{}",cpUserTokenRedisKey);
//                    userJsonStr = redisTemplateUtil.getJSON(cpUserTokenRedisKey);
//                    log.debug("userJsonStr:{}",userJsonStr);
//                    if(StringUtil.isNotEmpty(userJsonStr))
//                    {
//                        accountId = basicConfig.getDefaultCpAccountId();
//                        userTokenRedisKey = cpUserTokenRedisKey;
//                    }
//                }
//
//                //如果缓存中没有，则重新走流程
//                if (StringUtil.isNotEmpty(userJsonStr)) {
//                    user = JSONObject.parseObject(userJsonStr, UserDto.class);
//                    doLoginFlag = false;//不需要重新登录
//                }
//            }

            //重新取数据
            if (doLoginFlag) {
                log.info("准备开始获取分布式锁......unionId:{},openId:{}", userDto.getUnionId(), userDto.getOpenId());
                boolean lock = false;
                String lockKey = RedisKeyConstant.WKBB_BASIC_USER_BACK + "lock:unionId_" + unionId;
                int retryCount = 0;
                while (!lock) {
                    try {
                        lock = redisTemplateUtil.tryLock(lockKey, userDto.getUnionId(), 120, TimeUnit.SECONDS);
                    } catch (Exception e) {
                        log.error("---------加锁失败,等待锁过期----------e:{}", e.getMessage());
                    }
                    if (lock) {//加锁成功
                        try{
                            user = userOpenService.doUserByOpen(routeFlag, loginType, miniApp, userDto);
                        }catch (Exception e){
                            log.error("---------登录异常----------e:{}", e.getMessage());
                        }finally {
                            try {
                                redisTemplateUtil.releaseLock(lockKey, userDto.getUnionId());
                            } catch (Exception e) {
                                log.error("---------释放锁异常----------e:{}", e.getMessage());
                            }
                        }
                    } else {
                        retryCount++;
                        if(retryCount>10){
                            log.info("加锁失败，重试超过10次，用户登录失败...unionId:{},openId:{}", userDto.getUnionId(), userDto.getOpenId());
                            break;
                        }
                        log.error("加锁失败,等待500ms重试...");
                        Thread.sleep(500L);
                    }
                }
            }

            //更新缓存redis
            if (null != user) {
                if(StringUtils.isEmpty(user.getOpenId())) {
                    if(StringUtils.isEmpty(userDto.getOpenId()))
                    {
                        if (loginType == LoginTypeEnum.MINI.getValue().shortValue()) {
                            user.setOpenId(userOpenService.getUserOpenId(loginType,miniApp,userDto.getUnionId(),userDto.getOpenId()));
                        }
                    }
                    else {
                        user.setOpenId(userDto.getOpenId());
                    }
                }

                //不同的小程序记录各自的openId
                if (loginType == LoginTypeEnum.MINI.getValue().intValue() && !accountId.equals(CommonConstant.VISIT_ACCOUNT_ID) && !StringUtils.isEmpty(userDto.getOpenId())) {
                    userOpenService.saveUserOpen(loginType, miniApp, accountId, user.getId(), unionId, userDto.getOpenId());
                }

                //企业号进入需要重置accountId更新key
//                if(!routeFlag) {
//                    Long newAccountId = user.getAccountId();
//                    log.info("accountId:{} newAccountId:{}",accountId,newAccountId);
//                    if(!accountId.equals(newAccountId))
//                    {
//                        userTokenRedisKey = String.format(tokenRedisKey, newAccountId, unionId);//绑定公众号模式
//                    }
//                }
//                更新缓存redis
//                log.info("userTokenRedisKey:{}",userTokenRedisKey);
//                redisTemplateUtil.set(userTokenRedisKey, user, RedisKeyConstant.EXPIRATION_TIME_1_YEAR);
            }

            //记录用户登录日志
            if (null != user) {
                try {
                    UserLoginLog userLoginLog = new UserLoginLog();
                    userLoginLog.setType(loginType.shortValue());
                    userLoginLog.setAccountId(user.getAccountId());
                    userLoginLog.setUserId(user.getId());
                    userLoginLog.setUnionId(user.getUnionId());
                    userLoginLog.setOpenId(userDto.getOpenId());

//                    redisTemplateUtil.set(redisKey, userDto, RedisKeyConstant.EXPIRATION_TIME_1_YEAR);

                    userService.addUserLoginLog(userLoginLog);
                }
                catch (Exception e) {
                    log.error("****写登录日志异常****");
                }
            }

            return new ResultDTO<UserDto>(user);

        } catch (Exception e) {
            log.error("****登录异常****");
            return new ResultDTO<UserDto>(ErrorCode.USER_LOGIN_FAILURE);
        }
    }

    @ApiOperation(value = "操作用户并返回用户信息")
    @RequestMapping(value = "/wxLogin", method = RequestMethod.POST)
    public ResultDTO<UserDto> wxLogin(@RequestBody UserDto userDto) {
        try {
            UserDto user = userOpenService.wxLogin(userDto);
            //记录用户登录日志
            if (null != user) {
                try {
                    UserLoginLog userLoginLog = new UserLoginLog();
                    userLoginLog.setType((short) 2);
                    userLoginLog.setAccountId(user.getAccountId());
                    userLoginLog.setUserId(user.getId());
                    userLoginLog.setUnionId(user.getUnionId());
                    userLoginLog.setOpenId(userDto.getOpenId());
                    userService.addUserLoginLog(userLoginLog);
                }
                catch (Exception e) {
                    log.error("****写登录日志异常****");
                }
            }

            if (user != null){
                //生成token
                String tokenRedisKey = RedisKeyConstant.WKBB_BASIC_USER_ROUTE + RedisKeyConstant.WKBB_BASIC_USER_ROUTE_TOKEN_UNIONID;
                TokenUtil tokenUtil = new TokenUtil(serviceConfig.getTokenSecretKey(), serviceConfig.getTokenAlgorithm());
                String token = tokenUtil.getToken(System.currentTimeMillis() + user.getId().toString());
                String userTokenRedisKey = String.format(tokenRedisKey, token);
                redisTemplateUtil.set(userTokenRedisKey,user,RedisKeyConstant.EXPIRATION_TIME_1_MONTH);
                user.setToken(token);
                return new ResultDTO<UserDto>(user);
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("****登录异常****");
        }
        return new ResultDTO<UserDto>(ErrorCode.USER_LOGIN_FAILURE);
    }

    @ApiOperation(value = "根据用户获取用户信息接口")
    @RequestMapping(value = "/getUserInfoByUser", method = RequestMethod.GET)
    public ResultDTO<UserInfoDto> getUserInfoByUser(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "组织ID", required = true) @RequestParam(name = "orgId", required = true) Long orgId,
            @ApiParam(value = "用户ID", required = true) @RequestParam(name = "userId", required = true) Long userId,
            @ApiParam(value = "用户角色（1教师2家长3学生4职员5游客）", required = true) @RequestParam(name = "roleType", required = true) Integer roleType) {

        log.info("***********getUserInfoByUser******apiVersion:{},orgId:{},userId:{},roleType:{}", apiVersion, orgId, userId, roleType);

        try {

            if (null == orgId || null == userId || null == roleType) {
                return new ResultDTO<>(ErrorCode.PARAM_MISSING);
            }

            UserInfoDto userInfoDto = userService.getUserInfoByUser(orgId, userId, roleType);

            return new ResultDTO<>(userInfoDto);

        } catch (Exception e) {
            log.error("***********getUserInfoByUser******", e);
            return new ResultDTO<>(ErrorCode.SYSTEM_EXCEPTION);
        }
    }


    @ApiOperation(value = "根据UserCode获取用户接口")
    @RequestMapping(value = "/getUserByUserCode", method = RequestMethod.GET)
    public ResultDTO<UserDto> getUserByUserCode(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "UserCode", required = true) @RequestParam(name = "userCode") String userCode) {
        log.info("***********getUserByUserCode******apiVersion:{},userCode:{}", apiVersion,userCode);

        try {
            if (StringUtils.isEmpty(userCode)) {
                return new ResultDTO<>(ErrorCode.PARAM_MISSING);
            }
            Map<String, Object> params = new HashMap<>();
            params.put("userCode", userCode);
            User user = userService.getByMapParams(params);
            if (user != null) {
                return new ResultDTO<>(BeanUtil.copyProperties(user, UserDto.class));
            }
            return new ResultDTO<>();
        } catch (Exception e) {
            log.error("***********getUserByUserCode******", e);
            return new ResultDTO<>(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    @ApiOperation(value = "批量获取用户昵称")
    @RequestMapping(value = "getNickName", method = RequestMethod.POST)
    public ResultDTO<List<NickNameDto>> getNickName(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "用户列表", required = true) @RequestBody(required = true) List<NickNameDto> nickNameDtos) {
        log.info("***********getNickName******apiVersion:{},nickNameDtos:{}", apiVersion, Arrays.toString(nickNameDtos.toArray()));

        try {
            return new ResultDTO<>(userOpenService.getNickName(nickNameDtos));
        } catch (Exception e) {
            log.error("***********getNickName******", e);
            return new ResultDTO<>(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    @ApiOperation(value = "清除昵称")
    @RequestMapping(value = "clearNickName", method = RequestMethod.DELETE)
    public ResultDTO clearNickName(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
//            @ApiParam(value = "学校ID", required = true) @RequestParam(value = "orgId", required = true) Long orgId,
            @ApiParam(value = "用户ID", required = true) @RequestParam(value = "userId", required = true) Long userId) {
        log.info("***********getNickName******apiVersion:{},userId:{}", apiVersion,  userId);
//        if (orgId == 0 || userId == 0) {
//            return new ResultDTO(ErrorCode.PARAM_MISSING);
//        }

        try {
            userOpenService.clearNickName( userId);

            return new ResultDTO<>();
        } catch (Exception e) {
            log.error("***********clearNickName******", e);
            return new ResultDTO<>(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    @ApiOperation(value = "根据手机号获取用户接口")
    @RequestMapping(value = "/getUserByMobile", method = RequestMethod.GET)
    public ResultDTO<UserInfoDto> getUserByMobile(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "手机号", required = true) @RequestParam(name = "mobile", required = true) String mobile) {
        log.info("***********getUserByMobile******apiVersion:{},mobile:{}", mobile);

        try {
            if (StringUtils.isEmpty(mobile)) {
                return new ResultDTO<UserInfoDto>(ErrorCode.PARAM_MISSING);
            }

            return new ResultDTO<UserInfoDto>(userService.getUserInfoByMobile(mobile));

        } catch (Exception e) {
            log.error("***********getUserByMobile******", e);
            return new ResultDTO<UserInfoDto>(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    @ApiOperation(value = "根据手机号获取用户信息接口")
    @RequestMapping(value = "/getUserInfoByMobile", method = RequestMethod.GET)
    public ResultDTO<UserDto> getUserInfoByMobile(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "账户ID", required = false) @RequestParam(name = "accountId", required = false) Long accountId,
            @ApiParam(value = "手机号", required = true) @RequestParam(name = "mobile", required = true) String mobile) {
        log.info("***********getUserInfoByMobile******apiVersion:{},mobile:{}", mobile);

        try {

            if (StringUtils.isEmpty(mobile)) {
                return new ResultDTO<UserDto>(ErrorCode.PARAM_MISSING);
            }

            UserDto userDto = userOpenService.getUserInfoByMobile(accountId, mobile);

            return new ResultDTO<UserDto>(userDto);

        } catch (Exception e) {
            log.error("***********getUserInfoByMobile******", e);
            return new ResultDTO<UserDto>(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    @ApiOperation(value = "根据ID获取用户接口")
    @RequestMapping(value = "/getUserById", method = RequestMethod.GET)
    public ResultDTO<UserInfoDto> getUserById(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "ID", required = true) @RequestParam(name = "userId", required = true) Long userId) {
        log.info("***********getUserById******apiVersion:{},userId:{}", userId);

        try {

            if (null == userId) {
                return new ResultDTO<UserInfoDto>(ErrorCode.PARAM_MISSING);
            }

            User user = userService.getByPrimaryKey(userId);

            UserInfoDto userInfoDto = null;
            if (user != null) {
                userInfoDto = new UserInfoDto();
                BeanUtils.copyProperties(user, userInfoDto);
            }

            return new ResultDTO<UserInfoDto>(userInfoDto);

        } catch (Exception e) {
            log.error("***********getUserById******", e);
            return new ResultDTO<UserInfoDto>(ErrorCode.SYSTEM_EXCEPTION);
        }
    }


    @ApiOperation(value = "根据ID获取用户接口（userInfo）")
    @RequestMapping(value = "/getUserInfo", method = RequestMethod.GET)
    public ResultDTO<UserInfoDto> getUserInfo(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "用户ID", required = true) @RequestParam(name = "userId", required = true) Long userId
    ) {
        log.info("***********getUserInfo******apiVersion:{},userId:{}", userId);
        try {

            if (null == userId) {
                return new ResultDTO<>(ErrorCode.PARAM_MISSING);
            }
            Map<String, Object> params = new HashMap<>(Constants.INIT_MAP_SIZE_5);
            params.put("userId", userId);
            UserInfoDto userInfoDto = userService.getUserInfoById(params);

            return new ResultDTO<>(userInfoDto);
        } catch (Exception e) {
            log.error("***********getUserInfo******", e);
            return new ResultDTO<>(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    @ApiOperation(value = "绑定用户接口")
    @RequestMapping(value = "/bindUser", method = RequestMethod.GET)
    public ResultDTO<Boolean> bindUser(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "账号ID", required = true) @RequestParam(name = "accountId", required = true) Long accountId,
            @ApiParam(value = "游客userId", required = true) @RequestParam(name = "visitorUserId", required = true) Long visitorUserId,
            @ApiParam(value = "真实userId", required = true) @RequestParam(name = "realUserId", required = true) Long realUserId) {
        log.info("***********bindUser******apiVersion:{},accountId:{},visitorUserId:{},realUserId:{}", apiVersion,accountId, visitorUserId, realUserId);

        try {

            if (null == accountId || null == visitorUserId || null == realUserId) {
                return new ResultDTO<Boolean>(ErrorCode.PARAM_MISSING);
            }

            Boolean bindFlag = userOpenService.bindUser(accountId, visitorUserId, realUserId);
            if(bindFlag)
            {
                // 清除昵称头像缓存
                ClearNickNameTask clearNickNameTask = new ClearNickNameTask(userOpenService,realUserId);
                ThreadPoolUtil.addTask(clearNickNameTask);
            }

            return new ResultDTO<Boolean>(bindFlag);

        } catch (Exception e) {
            log.error("***********bindUser******", e);
            return new ResultDTO<Boolean>(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    @ApiOperation(value = "获取user的union信息接口")
    @RequestMapping(value = "/getUnionInfo", method = RequestMethod.GET)
    public ResultDTO<UserUnionDto> getUnionInfo(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "账号ID", required = false) @RequestParam(name = "accountId", required = false) Long accountId,
            @ApiParam(value = "unionId", required = false) @RequestParam(name = "unionId", required = false) String unionId,
            @ApiParam(value = "userId", required = true) @RequestParam(name = "userId", required = true) Long userId) {
        log.info("***********getUnionInfo******apiVersion:{},accountId:{},unionId:{},userId:{}", apiVersion, accountId, unionId, userId);
        try {
            if (null == userId) {
                return new ResultDTO<UserUnionDto>(ErrorCode.PARAM_MISSING);
            }
            UserUnionDto userUnionDto = userOpenService.getUnionInfo(accountId, unionId, userId);
            return new ResultDTO<UserUnionDto>(userUnionDto);
        } catch (Exception e) {
            log.error("***********getUnionInfo******", e);
            return new ResultDTO<UserUnionDto>(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    @ApiOperation(value = "获取user的union信息接口")
    @RequestMapping(value = "/getUserUnionList", method = RequestMethod.GET)
    public ResultDTO<List<UserUnionDto>> getUserUnionList(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "账号ID", required = false) @RequestParam(name = "accountId", required = false) Long accountId,
            @ApiParam(value = "unionId", required = false) @RequestParam(name = "unionId", required = false) String unionId,
            @ApiParam(value = "userId", required = false) @RequestParam(name = "userId", required = false) Long userId) {
        log.info("***********getUserUnionList******accountId:{},unionId:{},userId:{}", accountId, unionId, userId);
        try {
            if (null == unionId || null == userId) {
                return new ResultDTO(ErrorCode.PARAM_MISSING);
            }

            Map<String, Object> userUnionParams = new HashMap<String, Object>();
            userUnionParams.put("accountId", accountId);
            userUnionParams.put("unionId", unionId);
            userUnionParams.put("userId", userId);

            return new ResultDTO(userOpenService.getUserUnionList(userUnionParams));
        } catch (Exception e) {
            log.error("***********getUserUnionList******", e);
            return new ResultDTO(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    @ApiOperation(value = "根据accountId,mobile查询此人是否已在该学校登记过")
    @RequestMapping(value = "/getUserExist", method = RequestMethod.GET)
    public ResultDTO<UserDto> getUserExist(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "账号ID", required = true) @RequestParam(name = "accountId", required = true) Long accountId,
            @ApiParam(value = "手机号", required = true) @RequestParam(name = "mobile", required = true) String mobile) {
        log.info("***********getUserExist******apiVersion:{},accountId:{},mobile:{}", apiVersion, accountId, mobile);
        try {
            if (null == accountId || StringUtils.isEmpty(mobile)) {
                return new ResultDTO(ErrorCode.PARAM_MISSING);
            }

            User user = userOpenService.getUserExistAccount(accountId, mobile);
            UserDto userDto = null;
            if (null != user) {
                userDto = new UserDto();
                BeanUtils.copyProperties(user, userDto);
            }

            return new ResultDTO<UserDto>(userDto);
        } catch (Exception e) {
            log.error("***********getUserExist******", e);
            return new ResultDTO(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    @ApiOperation(value = "更改手机号接口")
    @RequestMapping(value = "/updateMobile", method = RequestMethod.POST)
    public ResultDTO<Boolean> updateMobile(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "角色类型（1教师2家长3学生4职员5游客）", required = true) @RequestParam(name = "roleType", required = true) Integer roleType,
            @ApiParam(value = "user对象", required = true) @RequestBody UserInfoDto userInfoDto) {
        try {
            if (null == roleType || null == userInfoDto || null == userInfoDto.getId() || null == userInfoDto.getOrgId()) {
                return new ResultDTO(ErrorCode.PARAM_MISSING);
            }
            //roleType可能是学生,老师,家长
            if (roleType == RoleTypeEnum.TEACHER.getValue() || roleType == RoleTypeEnum.EMPLOYEE.getValue()) {
                EmployeeInfoDto employeeInfoDto = new EmployeeInfoDto();
                BeanUtils.copyProperties(userInfoDto, employeeInfoDto, new String[]{"id"});
                employeeInfoDto.setUserId(userInfoDto.getId());
                teacherManageService.updateMobile(employeeInfoDto);
                return new ResultDTO(true);
            } else if (roleType == RoleTypeEnum.FAMILY.getValue()) {
                FamilyInfoDto familyInfoDto = new FamilyInfoDto();
                BeanUtils.copyProperties(userInfoDto, familyInfoDto, new String[]{"id"});
                familyInfoDto.setUserId(userInfoDto.getId());
                familyService.updateMobile(familyInfoDto);
                return new ResultDTO(true);
            } else if (roleType == RoleTypeEnum.TOURIST.getValue()) {
                return new ResultDTO(ErrorCode.TOURISTS_CAN_NOT_UPDATED);
            } else {
                return new ResultDTO(ErrorCode.ROLE_TYPE_ERROR);
            }
        } catch (Exception e) {
            log.error("***********updateMobile******", e);
            return new ResultDTO(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    @ApiOperation(value = "更新user信息接口")
    @RequestMapping(value = "/updateUser", method = RequestMethod.POST)
    public ResultDTO<Boolean> updateUser(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "角色类型（1教师2家长3学生4职员5游客）", required = true) @RequestParam(name = "roleType", required = true) Integer roleType,
            @ApiParam(value = "user对象", required = true) @RequestBody UserInfoDto userInfoDto) {
        log.info("***********updateUser******apiVersion:{},roleType:{},userInfoDto:{}", apiVersion, roleType, userInfoDto);
        try {
            if (null == roleType || null == userInfoDto || null == userInfoDto.getId() || null == userInfoDto.getOrgId()) {
                return new ResultDTO(ErrorCode.PARAM_MISSING);
            }
            //roleType可能是学生,老师,家长
            if (roleType == RoleTypeEnum.TEACHER.getValue() || roleType == RoleTypeEnum.EMPLOYEE.getValue()) {
                EmployeeInfoDto employeeInfoDto = new EmployeeInfoDto();
                BeanUtils.copyProperties(userInfoDto, employeeInfoDto, new String[]{"id"});
                employeeInfoDto.setUserId(userInfoDto.getId());

                Map<String, Object> params = new HashMap<>(2);
                params.put("orgId", userInfoDto.getOrgId());
                params.put("userId", userInfoDto.getId());
                Employee employee = employeeService.getByMapParams(params);
                if(null != employee)
                {
                    employeeInfoDto.setUserType(employee.getUserType());
                }
                teacherManageService.updateTeacher(employeeInfoDto, null);

                return new ResultDTO(true);
            } else if (roleType == RoleTypeEnum.FAMILY.getValue()) {
                FamilyInfoDto familyInfoDto = new FamilyInfoDto();
                BeanUtils.copyProperties(userInfoDto, familyInfoDto, new String[]{"id"});
                familyInfoDto.setUserId(userInfoDto.getId());
                familyService.update(familyInfoDto, null);
                return new ResultDTO(true);
            } else if (roleType == RoleTypeEnum.STUDENT.getValue()) {
                StudentInfoDto studentInfoDto = new StudentInfoDto();
                BeanUtils.copyProperties(userInfoDto, studentInfoDto, new String[]{"id"});
                studentInfoDto.setUserId(userInfoDto.getId());
                studentService.update(studentInfoDto, null);
                return new ResultDTO(true);
            } else if (roleType == RoleTypeEnum.TOURIST.getValue()) {
                return new ResultDTO(ErrorCode.TOURISTS_CAN_NOT_UPDATED);
            } else {
                return new ResultDTO(ErrorCode.ROLE_TYPE_ERROR);
            }
        } catch (Exception e) {
            log.error("***********updateUser******", e);
            return new ResultDTO(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    @ApiOperation(value = "修改用户信息(含手机号)接口")
    @RequestMapping(value = "/updateUserInfo", method = RequestMethod.POST)
    public ResultDTO<Boolean> updateUserInfo(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "角色类型（1教师2家长3学生4职员5游客）", required = true) @RequestParam(name = "roleType", required = true) Integer roleType,
            @ApiParam(value = "user对象", required = true) @RequestBody UserInfoDto userInfoDto) {

        log.info("***********updateUserInfo******apiVersion:{},roleType:{},userInfoDto:{}", apiVersion, roleType, userInfoDto);
        try {
            if (null == roleType || null == userInfoDto || null == userInfoDto.getId() || null == userInfoDto.getOrgId()) {
                return new ResultDTO(ErrorCode.PARAM_MISSING);
            }

            Long userId = userInfoDto.getId();
            String redisKey = RedisKeyConstant.WKBB_BASIC + "user:info:user_" + userId;
            Object userInfo = redisTemplateUtil.get(redisKey);
            if (null != userInfo) {
                Thread.sleep(5000L);//延迟一下
            }

            redisTemplateUtil.set(redisKey,userId,RedisKeyConstant.EXPIRATION_TIME_10);

            //roleType可能是学生,老师,家长
            if (roleType == RoleTypeEnum.TEACHER.getValue() || roleType == RoleTypeEnum.EMPLOYEE.getValue()) {
                EmployeeInfoDto employeeInfoDto = new EmployeeInfoDto();
                BeanUtils.copyProperties(userInfoDto, employeeInfoDto, new String[]{"id"});
                employeeInfoDto.setUserId(userInfoDto.getId());

                if(StringUtil.isNotEmpty(employeeInfoDto.getMobile())) {
                    teacherManageService.updateMobile(employeeInfoDto);//手机号
                }

                Thread.sleep(3000L);//延迟一下

                Map<String, Object> params = new HashMap<>(2);
                params.put("orgId", userInfoDto.getOrgId());
                params.put("userId", userInfoDto.getId());
                Employee employee = employeeService.getByMapParams(params);
                if(null != employee)
                {
                    employeeInfoDto.setUserType(employee.getUserType());
                }

                teacherManageService.updateTeacher(employeeInfoDto, null);

            }
            else if (roleType == RoleTypeEnum.FAMILY.getValue()) {
                FamilyInfoDto familyInfoDto = new FamilyInfoDto();
                BeanUtils.copyProperties(userInfoDto, familyInfoDto, new String[]{"id"});
                familyInfoDto.setUserId(userInfoDto.getId());

                if(StringUtil.isNotEmpty(familyInfoDto.getMobile())) {
                    familyService.updateMobile(familyInfoDto);
                }

                Thread.sleep(5000L);//延迟一下

                familyService.update(familyInfoDto, null);
            }
            else if (roleType == RoleTypeEnum.STUDENT.getValue()) {
                StudentInfoDto studentInfoDto = new StudentInfoDto();
                BeanUtils.copyProperties(userInfoDto, studentInfoDto, new String[]{"id"});
                studentInfoDto.setUserId(userInfoDto.getId());

                Thread.sleep(1000L);//延迟一下

                studentService.update(studentInfoDto, null);
            }

            //清除缓存
            redisTemplateUtil.delete(redisKey);

            return new ResultDTO(true);

        } catch (Exception e) {
            log.error("***********updateUserInfo异常******", e);
            return new ResultDTO(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    @ApiOperation(value = "获取用户微信信息接口")
    @RequestMapping(value = "/getUserOpenByUser", method = RequestMethod.GET)
    public ResultDTO<UserOpenDto> getUserOpenByUser(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "类型(1公众号 2小程序)", required = true) @RequestParam(name = "type", required = true) Integer type,
            @ApiParam(value = "账号ID", required = true) @RequestParam(name = "accountId", required = true) Long accountId,
            @ApiParam(value = "组织ID", required = false) @RequestParam(name = "orgId", required = false) Long orgId,
            @ApiParam(value = "用户ID", required = true) @RequestParam(name = "userId", required = true) Long userId) {
        log.info("***********getUserOpenByUser******apiVersion:{},accountId:{},orgId:{},userId:{}", apiVersion, accountId, orgId, userId);

        try {

            if (null == accountId || null == userId) {
                return new ResultDTO<>(ErrorCode.PARAM_MISSING);
            }

            //优化根据orgId获取
            Map<String, Object> params = new HashMap<>();
            params.put("type", type);
            params.put("accountId", accountId);
            params.put("orgId", orgId);
            params.put("userId", userId);
            UserOpen userOpen = userService.getUserOpenByUser(params);

            UserOpenDto userOpenDto = new UserOpenDto();
            if (null != userOpen) {
                BeanUtils.copyProperties(userOpen, userOpenDto);
            }

            return new ResultDTO<UserOpenDto>(userOpenDto);

        } catch (Exception e) {
            log.error("***********getUserOpenByUser******", e);
            return new ResultDTO<>(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    @ApiOperation(value = "获取用户微信信息接口")
    @RequestMapping(value = "/getUserOpen", method = RequestMethod.GET)
    public ResultDTO<UserOpenDto> getUserOpen(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "类型(1公众号 2小程序)", required = true) @RequestParam(name = "type", required = true) Integer type,
            @ApiParam(value = "账号ID", required = true) @RequestParam(name = "accountId", required = true) Long accountId,
            @ApiParam(value = "组织ID", required = false) @RequestParam(name = "orgId", required = false) Long orgId,
            @ApiParam(value = "用户ID", required = false) @RequestParam(name = "userId", required = false) Long userId,
            @ApiParam(value = "用户unionId", required = false) @RequestParam(name = "unionId", required = false) String unionId,
            @ApiParam(value = "用户openId", required = false) @RequestParam(name = "openId", required = false) String openId) {

        log.info("***********getUserOpen******accountId:{},orgId:{},userId:{},unionId:{},openId:{}",  accountId, orgId, userId,unionId,openId);

        try {

            if (null == accountId) {
                return new ResultDTO<>(ErrorCode.PARAM_MISSING);
            }

            //优化根据orgId获取
            Map<String, Object> params = new HashMap<>();
            params.put("type", type);
            params.put("accountId", accountId);
            params.put("orgId", orgId);
            params.put("userId", userId);
            params.put("unionId", unionId);
            params.put("openId", openId);
            UserOpen userOpen = userService.getUserOpenByUser(params);

            UserOpenDto userOpenDto = new UserOpenDto();
            if (null != userOpen) {
                BeanUtils.copyProperties(userOpen, userOpenDto);
            }

            return new ResultDTO<UserOpenDto>(userOpenDto);

        } catch (Exception e) {
            log.error("***********getUserOpen******", e);
            return new ResultDTO<>(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    @ApiOperation(value = "根据验证码获取用户接口")
    @RequestMapping(value = "/getUserBySms", method = RequestMethod.GET)
    public ResultDTO<UserDto> getUserBySms(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "账户ID", required = false) @RequestParam(name = "accountId", required = false) Long accountId,
            @ApiParam(value = "手机号", required = true) @RequestParam(name = "mobile", required = true) String mobile,
            @ApiParam(value = "短信验证码", required = true) @RequestParam(name = "smsCode", required = true) String smsCode) {

        log.info("***********getUserBySms******apiVersion:{},mobile:{}", mobile);

        try {
            if (StringUtils.isEmpty(mobile) || StringUtils.isEmpty(smsCode)) {
                return new ResultDTO<UserDto>(ErrorCode.PARAM_MISSING);
            }

            //短信验证码检验
            ErrorCode errorCode = SmsCodeUtil.verifyCode(redisTemplateUtil, mobile, SmsTypeEnum.OTHER.getValue(), smsCode);
            if (!ErrorCode.SUCCESS.getCode().equals(errorCode.getCode())) {
                return new ResultDTO<>(errorCode);
            }

            UserDto userDto = userOpenService.getUserInfoByMobile(accountId, mobile);

            return new ResultDTO<UserDto>(userDto);

        } catch (Exception e) {
            log.error("***********getUserBySms******", e);
            return new ResultDTO<UserDto>(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    @ApiOperation(value = "学校公众号用户绑定手机号接口")
    @RequestMapping(value = "/bindUserMobile", method = RequestMethod.POST)
    public ResultDTO<Boolean> bindUserMobile(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "账号ID", required = true) @RequestParam(name = "accountId", required = true) Long accountId,
            @ApiParam(value = "组织ID", required = true) @RequestParam(name = "orgId", required = true) Long orgId,
            @ApiParam(value = "用户openId", required = true) @RequestParam(name = "openId", required = true) String openId,
            @ApiParam(value = "用户手机号", required = true) @RequestParam(name = "mobile", required = true) String mobile) {
        log.info("***********bindUserMobile******apiVersion:{},accountId:{},openId:{},mobile:{}", accountId, openId, mobile);

        try {

            if (null == accountId || StringUtils.isEmpty(openId) || StringUtils.isEmpty(mobile)) {
                return new ResultDTO<Boolean>(ErrorCode.PARAM_MISSING);
            }

            //查询用户是否存在
            User user = userOpenService.getUserExistOrg(orgId, mobile);
            if (null == user) {
                return new ResultDTO<Boolean>(ErrorCode.USER_NOT_EXIST);
            }

            Boolean bindFlag = userOpenService.bindUserMobile(accountId, orgId, user.getId(), null, openId, mobile);

            if (bindFlag) {
                WechatKfMessageDto wechatKfMessageDto = new WechatKfMessageDto();
                wechatKfMessageDto.setAccountId(accountId);
                wechatKfMessageDto.setOpenId(openId);
                wechatKfMessageDto.setContent("恭喜！您已认证成功");

                log.info("***********bindUserMobile***sendWxKfMsg begin***wechatKfMessageDto:{}", wechatKfMessageDto);
                wxFeignService.sendWxKfMsg(wechatKfMessageDto);
                log.info("***********bindUserMobile***sendWxKfMsg end***");
            }

            return new ResultDTO<Boolean>(bindFlag);

        } catch (Exception e) {
            log.error("***********bindUserMobile******", e);
            return new ResultDTO<Boolean>(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    @ApiOperation(value = "扫码配置用户登录")
    @RequestMapping(value = "/loginByPwd", method = RequestMethod.GET)
    public ResultDTO<List<UserDto>> loginByPwd(
            @ApiParam(value = "接口版本", defaultValue = VersionConstant.V1, required = true) @PathVariable(name = "apiVersion") String apiVersion,
            @ApiParam(value = "账号", required = false) @RequestParam(name = "account", required = false) String account,
            @ApiParam(value = "密码", required = false) @RequestParam(name = "password", required = false) String password) {

        log.info("**********loginByPwd********apiVersion:{},account:{},password:{}", apiVersion, account, password);
        if (com.alibaba.druid.util.StringUtils.isEmpty(account) || com.alibaba.druid.util.StringUtils.isEmpty(password)) {
            return new ResultDTO<>(ErrorCode.PARAM_MISSING);
        }

        try {

            List<UserDto> userList = userService.loginByPwd(account, password);

            return new ResultDTO<List<UserDto>>(userList);

        } catch (Exception e) {
            log.error("**********loginByPwd********", e);
            return new ResultDTO<>(false);
        }
    }

    @ApiOperation(value = "扫码配置用户登录生成token")
    @RequestMapping(value = "/getLoginToken", method = RequestMethod.GET)
    public ResultDTO<String> getLoginToken(
            @ApiParam(value = "接口版本", defaultValue = VersionConstant.V1, required = true) @PathVariable(name = "apiVersion") String apiVersion,
            @ApiParam(value = "账户ID", required = false) @RequestParam(name = "accountId", required = false) Long accountId,
            @ApiParam(value = "组织ID", required = false) @RequestParam(name = "orgId", required = false) Long orgId,
            @ApiParam(value = "用户ID", required = false) @RequestParam(name = "userId", required = false) Long userId) {

        log.info("**********getLoginToken********apiVersion:{},orgId:{},userId:{}", apiVersion, accountId, orgId, userId);
        if (orgId == null || userId == null) {
            return new ResultDTO<>(ErrorCode.PARAM_MISSING);
        }

        try {

            UserDto userDto = userService.getUserInfoManage(accountId, orgId, userId, false);

            //组装TOKEN KEY
//            String key = accountId + "-" + orgId + "-" + userId;
            String key = orgId + "-" + userId;

            //生成token值
            TokenUtil tokenUtil = new TokenUtil(serviceConfig.getTokenSecretKey(), serviceConfig.getTokenAlgorithm());
            String token = tokenUtil.getToken(key);

            String redisKey = RedisKeyConstant.WKBB_BASIC_USER_BACK + RedisKeyConstant.WKBB_BASIC_USER_BACK_TOKEN + token;

            redisTemplateUtil.set(redisKey, userDto, RedisKeyConstant.EXPIRATION_TIME_1_YEAR);

            log.info("**********getLoginToken********key:{},token:{}", key, token);

            return new ResultDTO<String>(token);

        } catch (Exception e) {
            log.error("**********getLoginToken********", e);
            return new ResultDTO<>(false);
        }
    }

    @ApiOperation(value = "通过Account和openId获取用户信息")
    @RequestMapping(value = "/getUserDtoByAccountAndOpen", method = RequestMethod.GET)
    public ResultDTO<UserDto> getUserDtoByAccountAndOpen(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "账号ID", required = true) @RequestParam(name = "accountId", required = true) Long accountId,
            @ApiParam(value = "用户openId", required = true) @RequestParam(name = "openId", required = true) String openId) {

        log.info("***********getUserDtoByAccountAndOpenId******apiVersion:{},accountId:{},openId:{}", apiVersion, accountId, openId);

        if (null == accountId || StringUtils.isEmpty(openId)) {
            return new ResultDTO<>(ErrorCode.PARAM_MISSING);
        }

        UserDto userDto = userOpenService.getUserDtoByAccountAndOpen(accountId, openId);

        return new ResultDTO<>(userDto);
    }

    @ApiOperation(value = "根据ID获取用户接口,返回roleType json字段")
    @RequestMapping(value = "/getUserInfoById", method = RequestMethod.GET)
    public ResultDTO<UserDto> getUserInfoById(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "ID", required = true) @RequestParam(name = "userId", required = true) Long userId) {
        log.info("***********getUserInfoById******apiVersion:{},userId:{}", userId);

        try {

            if (null == userId) {
                return new ResultDTO<UserDto>(ErrorCode.PARAM_MISSING);
            }

            User user = userService.getByPrimaryKey(userId);

            UserDto userDto = null;
            if (user != null) {
                userDto = new UserDto();
                BeanUtils.copyProperties(user, userDto);
            }

            return new ResultDTO<UserDto>(userDto);

        } catch (Exception e) {
            log.error("***********getUserInfoById******", e);
            return new ResultDTO<UserDto>(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    @ApiOperation(value = "用户绑定学校公众号接口")
    @RequestMapping(value = "/mpBindUser", method = RequestMethod.POST)
    public ResultDTO<Boolean> mpBindUser(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "账号ID", required = true) @RequestParam(name = "accountId", required = true) Long accountId,
            @ApiParam(value = "用户ID", required = true) @RequestParam(name = "userId", required = true) Long userId,
            @ApiParam(value = "用户unionId", required = false) @RequestParam(name = "unionId", required = false) String unionId,
            @ApiParam(value = "用户openId", required = true) @RequestParam(name = "openId", required = true) String openId) {

        log.info("***********mpBindUser******accountId:{},userId:{},unionId:{},openId:{}", accountId, userId, unionId, openId);

        try {

            if (null == accountId || null == userId || StringUtils.isEmpty(openId)) {
                log.error("*****mpBindUser 参数错误*******");
                return new ResultDTO<Boolean>(false);
            }

            User user = userService.getByPrimaryKey(userId);
            if (null == user) {
                log.error("********mpBindUser 用户不存在*******");
                return new ResultDTO<Boolean>(ErrorCode.USER_NOT_EXIST);
            }

            String roleTypeJsonStr = JSON.toJSONString(user.getRoleType());
            log.debug("*************mpBindUser getUserInfo****************roleTypeJsonStr:{}", roleTypeJsonStr);
            List<RoleTypeJsonDto> roleTypeJsonDtoList = JSONObject.parseArray(roleTypeJsonStr, RoleTypeJsonDto.class);
            for (RoleTypeJsonDto roleTypeJsonDto : roleTypeJsonDtoList) {
                if (null != roleTypeJsonDto.getOrgId()) {
                    Long orgId = roleTypeJsonDto.getOrgId();
                    log.info("*************mpBindUser orgId:{}**************", orgId);
                    if (null != orgId || orgId != 0) {
                        ResultDTO<AccountDto> resultDTO = wxFeignService.getAccountByOrg(orgId);
                        if (resultDTO.isSuccess()) {
                            AccountDto account = resultDTO.getData();
                            log.debug("**********mpBindUser***********accountId:{}, account:{}**********", accountId, account);
                            if (null != account && accountId.equals(account.getId())) {

                                //查询用户是否存在
                                User userInfo = userOpenService.getUserExistOrg(orgId, user.getMobile());
                                log.debug("********mpBindUser 用户{}该组织{}下是否存在{}*******", userId, orgId, userInfo);
                                if (null != userInfo) {
                                    log.info("*************mpBindUser begin**************");
                                    Boolean bindFlag = userOpenService.bindUserMobile(accountId, orgId, user.getId(), unionId, openId, user.getMobile());
                                    log.info("*************mpBindUser end bindFlag:{}*******", bindFlag);
                                }
                            }
                        }
                    }
                }
            }

            return new ResultDTO<Boolean>(true);

        } catch (Exception e) {
            log.error("***********bindUserMobile 错误******", e);
            return new ResultDTO<Boolean>(false);
        }
    }

    @ApiOperation(value = "用户是否授权公众号(true:是 false:否)")
    @RequestMapping(value = "/userIsBindMp", method = RequestMethod.GET)
    public ResultDTO<Boolean> userIsBindMp(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "账号ID", required = true) @RequestParam(name = "accountId", required = true) Long accountId,
            @ApiParam(value = "ID", required = true) @RequestParam(name = "userId", required = true) Long userId) {
        log.info("***********userIsBindMp******accountId:{},userId:{}", accountId, userId);

        try {

            if (null == userId) {
                return new ResultDTO(ErrorCode.PARAM_MISSING);
            }

            User user = userService.getByPrimaryKey(userId);
            if (null == user) {
                log.error("********userIsBindMp 用户不存在*******");
                return new ResultDTO<Boolean>(ErrorCode.USER_NOT_EXIST);
            }

            Boolean isBind = true;
            String roleTypeJsonStr = JSON.toJSONString(user.getRoleType());
            log.debug("*************userIsBindMp****************roleTypeJsonStr:{}", roleTypeJsonStr);
            List<RoleTypeJsonDto> roleTypeJsonDtoList = JSONObject.parseArray(roleTypeJsonStr, RoleTypeJsonDto.class);
            for (RoleTypeJsonDto roleTypeJsonDto : roleTypeJsonDtoList) {
                if (null != roleTypeJsonDto.getOrgId()) {
                    Long orgId = roleTypeJsonDto.getOrgId();

                    ResultDTO<AccountDto> resultDTO = wxFeignService.getAccountByOrg(orgId);
                    if (resultDTO.isSuccess()) {
                        AccountDto account = resultDTO.getData();
                        log.debug("**********userIsBindMp***********accountId:{},account:{}**********", accountId, account);
                        if (null != account && accountId.equals(account.getId())) {

                            //查询用户是否存在
                            User userInfo = userOpenService.getUserExistOrg(orgId, user.getMobile());
                            log.debug("********userIsBindMp 用户{}该组织{}下是否存在{}*******", userId, orgId, userInfo);
                            if (null != userInfo) {
                                UserOpen userOpen = userOpenService.getUserOpen(accountId, orgId, userId);
                                if (null == userOpen) {
                                    isBind = false;
                                    break;
                                }
                            }
                        }
                    }
                }
            }
            log.info("*************userIsBindMp isBind:{}**************", isBind);

            return new ResultDTO(isBind);

        } catch (Exception e) {
            log.error("***********userIsBindMp 错误******", e);
            return new ResultDTO(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    @ApiOperation(value = "获取多个用户手机号")
    @RequestMapping(value = "/getUserMobileList", method = RequestMethod.POST)
    public ResultDTO<List<UserDto>> getUserMobileList(
            @RequestBody List<ImUserDto> imUserDto) {

        if (null == imUserDto) {
            return new ResultDTO<>(ErrorCode.PARAM_MISSING);
        }
        try {
            List<UserDto> userDto = userOpenService.getUserMobileList(imUserDto);
            return new ResultDTO<>(userDto);
        } catch (Exception e) {
            log.error("*************userIsBindMp getUserMobileList:{}**************ImUserDto:{}", e);
        }
        return new ResultDTO<>();
    }


	@ApiOperation(value = "修复优图数据")
    @RequestMapping(value = "/repairYouTu", method = RequestMethod.GET)
    public ResultDTO<Object> repairYouTu(){
        try{
            log.info("*************userIsBindMp repairYouTu:{}**************");
            userFaceService.repairYouTu();
            return new ResultDTO<Object>();
        }catch (Exception e){
            log.error("*************userIsBindMp repairYouTu:{}**************", e);
        }
        return new ResultDTO<>();

    }
	
	@ApiOperation(value = "修复用户头像数据")
    @RequestMapping(value = "/repairBasicHeadUrl", method = RequestMethod.GET)
    public ResultDTO<Object> repairBasicHeadUrl(
            @ApiParam(value = "修改前的字符串,如:cos.wsbjy.com", required = true) @RequestParam(name = "oldReplace", required = true) String oldReplace,
            @ApiParam(value = "修改后的字符串,如picshcos.wkbaobao.com", required = true) @RequestParam(name = "newReplace", required = true) String newReplace
    ){
        try{
            if (StringUtil.isEmptyIgnoreBlank(oldReplace)||StringUtil.isEmptyIgnoreBlank(newReplace)) {
                return new ResultDTO<>(ErrorCode.PARAM_MISSING);
            }

            log.info("*************userIsBindMp repairBasicHeadUrl:{}**************");
            userOpenService.repairBasicHeadUrl(oldReplace,newReplace);
            return new ResultDTO<Object>();
        }catch (Exception e){
            log.error("*************userIsBindMp repairBasicHeadUrl:{}**************", e);
        }
        return new ResultDTO<>();

    }

    @ApiOperation(value = "根据orgId清除人脸相关数据接口")
    @PostMapping(value = "deleteFaceData")
    public ResultDTO deleteFaceData(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "学校ID", required = true) @RequestParam(name = "orgId", required = true) Long orgId) {
        try {
            //在此验证必传参数
            if (null == orgId) {
                return new ResultDTO<>(ErrorCode.PARAM_MISSING);
            }
            userFaceService.deleteFaceData(orgId);
            return new ResultDTO();
        } catch (Exception e) {
            log.error("*************deleteFaceData*************异常:{}", e);
            return new ResultDTO(false);
        }
    }

    @ApiOperation(value = "根据orgId清除用户相关数据接口")
    @PostMapping(value = "deleteUserData")
    public ResultDTO deleteUserData(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "学校ID", required = true) @RequestParam(name = "orgId", required = true) Long orgId) {
        try {
            //在此验证必传参数
            if (null == orgId) {
                return new ResultDTO<>(ErrorCode.PARAM_MISSING);
            }
            userService.deleteUserData(orgId);
            return new ResultDTO();
        } catch (Exception e) {
            log.error("*************deleteUserData*************异常:{}", e);
            return new ResultDTO(false);
        }
    }

    @ApiOperation(value = "根据orgId查询人脸相关数据接口")
    @GetMapping(value = "getFaceData")
    public ResultDTO getFaceData(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "学校ID", required = true) @RequestParam(name = "orgId", required = true) Long orgId) {
        try {
            //在此验证必传参数
            if (null == orgId) {
                return new ResultDTO<>(ErrorCode.PARAM_MISSING);
            }
            Boolean bool = false;
            List<YoutuPerson> youtuPersonList = userFaceService.getFaceData(orgId);
            if (CollectionUtils.isNotEmpty(youtuPersonList)) {
                bool = true;
            }
            return new ResultDTO(bool);
        } catch (Exception e) {
            log.error("*************getFaceData*************异常:{}", e);
            return new ResultDTO(false);
        }
    }

    @ApiOperation(value = "根据orgId查询用户相关数据接口")
    @GetMapping(value = "getUserData")
    public ResultDTO getUserData(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "学校ID", required = true) @RequestParam(name = "orgId", required = true) Long orgId){
        try {
            //在此验证必传参数
            if (null == orgId) {
                return new ResultDTO<>(ErrorCode.PARAM_MISSING);
            }
            Boolean bool = false;
            Map<String,Object> paramMap = new HashMap();
            paramMap.put("orgId",orgId);
            paramMap.put("status",1);
            List<User> userList = userService.getListByMapParams(paramMap);
            if(CollectionUtils.isNotEmpty(userList)){
                bool = true;
            }
            return new ResultDTO(bool);
        } catch (Exception e) {
            log.error("*************getUserData*************异常:{}", e);
            return new ResultDTO(false);
        }
    }

    @ApiOperation(value = "修复智慧校园用户微信号")
    @RequestMapping(value = "/repairUserSmart", method = RequestMethod.GET)
    public ResultDTO<Object> repairUserSmart(){
        try{
            log.info("*************userIsBindMp repairUserSmart:{}**************");
            userOpenService.repairUserSmart();
            return new ResultDTO<Object>();
        }catch (Exception e){
            log.error("*************userIsBindMp repairUserSmart:{}**************", e);
        }
        return new ResultDTO<>();

    }

    @ApiOperation(value = "获取第三方用户微信ID")
    @RequestMapping(value = "/getSmartWxUserIdByUserId", method = RequestMethod.GET)
    public ResultDTO<UserSmartDto> getSmartWxUserIdByUserId(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "学校ID", required = true) @RequestParam(name = "orgId", required = true) Long orgId,
            @ApiParam(value = "用户类型", required = true) @RequestParam(name = "roleType", required = true) Integer roleType,
            @ApiParam(value = "用户ID", required = true) @RequestParam(name = "userId", required = true) Long userId){
        try{
            log.info("*************getSmartWxUserIdByUserId:{}**************orgId:{},roleType:{}，userId:{}",orgId,roleType,userId);
            UserSmart userSmart = userService.getUserSmart(orgId,userId,roleType);
            if(userSmart!=null){
                UserSmartDto userSmartDto = new UserSmartDto();
                BeanUtils.copyProperties(userSmart, userSmartDto);
                return new ResultDTO<UserSmartDto>(userSmartDto);
            }
        }catch (Exception e){
            log.error("*************getSmartWxUserIdByUserId:{}**************", e);
        }
        return new ResultDTO<>();

    }

    @ApiOperation(value = "按角色统计学校用户数据(全校、年级、班级)")
    @GetMapping(value = "/getUserCount")
    public ResultDTO<Integer> getUserCount(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion") String apiVersion,
            @ApiParam(value = "类型(1教师 2家长 3学生 4全校教师学生 5全校用户）", required = true) @RequestParam(name = "userStatRoleType", required = true) UserStatRoleTypeEnum userStatRoleType,
            @ApiParam(value = "组织ID", required = true) @RequestParam(name = "orgId", required = true) Long orgId,
            @ApiParam(value = "年级ID", required = false) @RequestParam(name = "gradeId", required = false) Long gradeId,
            @ApiParam(value = "班级ID", required = false) @RequestParam(name = "classId", required = false) Long classId)
    {

        try{
            log.info("********getUserCount:{}*******userStatRoleType:{},orgId:{},gradeId:{},classId:{}",userStatRoleType,orgId, gradeId, classId);
            int count = userService.getUserCount(userStatRoleType, orgId, gradeId, classId);
            return new ResultDTO<Integer>(count);
        }catch (Exception e){
            log.error("*******getUserCount******", e);
        }
        return new ResultDTO<Integer>(true);
    }

    @ApiOperation(value = "清除用户绑定关系")
    @RequestMapping(value = "/clearBindUser", method = RequestMethod.GET)
    public ResultDTO<Boolean> clearBindUser(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "组织ID", required = true) @RequestParam(name = "orgId", required = true) Long orgId,
            @ApiParam(value = "用户手机号", required = true) @RequestParam(name = "mobile", required = true) String mobile) {

        log.info("***********clearBindUser******orgId:{},mobile:{}", orgId, mobile);
        try {

            if (null == orgId || StringUtils.isEmpty(mobile)) {
                return new ResultDTO<Boolean>(ErrorCode.PARAM_MISSING);
            }

            boolean flag = userService.clearBindUser(orgId,mobile);

            return new ResultDTO<Boolean>(flag);

        } catch (Exception e) {
            log.error("***********clearBindUser******", e);
            return new ResultDTO<Boolean>(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    @ApiOperation(value = "清除用户绑定关系(手机号)")
    @RequestMapping(value = "/clearBindUserByMobile", method = RequestMethod.GET)
    public ResultDTO<Boolean> clearBindUserByMobile(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "用户手机号", required = true) @RequestParam(name = "mobile", required = true) String mobile) {

        log.info("***********clearBindUserByMobile******mobile:{}", mobile);
        try {

            if (StringUtils.isEmpty(mobile)) {
                return new ResultDTO<Boolean>(ErrorCode.PARAM_MISSING);
            }

            boolean flag = userService.clearBindUserByMobile(mobile);

            return new ResultDTO<Boolean>(flag);

        } catch (Exception e) {
            log.error("***********clearBindUserByMobile******", e);
            return new ResultDTO<Boolean>(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    @ApiOperation(value = "清除学校用户绑定关系(迁移公众号)")
    @RequestMapping(value = "/clearOrgBindUser", method = RequestMethod.POST)
    public ResultDTO<Boolean> clearOrgBindUser(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "组织ID", required = true) @RequestParam(name = "orgId", required = true) Long orgId) {

        log.info("***********clearBindUser******orgId:{}", orgId);
        try {

            if (null == orgId) {
                return new ResultDTO<Boolean>(ErrorCode.PARAM_MISSING);
            }

            userService.clearOrgBindUser(orgId);

            return new ResultDTO<Boolean>(true);

        } catch (Exception e) {
            log.error("***********clearBindUser******", e);
            return new ResultDTO<Boolean>(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    @ApiOperation(value = "根据mobile查询此人所在学校公众号")
    @RequestMapping(value = "/getAccountByMobile", method = RequestMethod.GET)
    public ResultDTO<List<AccountInfoDto>> getAccountByMobile(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "手机号", required = true) @RequestParam(name = "mobile", required = true) String mobile) {
        log.info("***********getAccountByMobile******apiVersion:{},mobile:{}", apiVersion, mobile);
        try {
            if (StringUtils.isEmpty(mobile)) {
                return new ResultDTO(ErrorCode.PARAM_MISSING);
            }

            List<AccountInfoDto> accountInfoList = userOpenService.getAccountByUserMobile(mobile);
            log.info("***********getAccountByMobile accountInfoList:{}******",accountInfoList);
            return new ResultDTO<List<AccountInfoDto>>(accountInfoList);
        } catch (Exception e) {
            log.error("***********getAccountByMobile******", e);
            return new ResultDTO(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    @ApiOperation(value = "获取企业微信用户微信号")
    @RequestMapping(value = "/getCpWxUserId", method = RequestMethod.GET)
    public ResultDTO<UserSmartDto> getCpWxUserId(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "学校ID", required = true) @RequestParam(name = "orgId", required = true) Long orgId,
            @ApiParam(value = "用户类型", required = true) @RequestParam(name = "roleType", required = true) Integer roleType,
            @ApiParam(value = "用户ID", required = true) @RequestParam(name = "userId", required = true) Long userId){
        try{
            log.info("*************getCpWxUserId:{}**************orgId:{},roleType:{}，userId:{}",orgId,roleType,userId);
            UserSmart userSmart = userService.getUserSmart(orgId,userId,roleType);
            if(userSmart!=null){
                //企微双身份是多用户数据同步，需要根据用户身份取wxUserId
                UserSmartDto userSmartDto = new UserSmartDto();
                BeanUtils.copyProperties(userSmart, userSmartDto);

                Map<String,Object> paramMap = new HashMap();
                paramMap.put("orgId",orgId);
                paramMap.put("userId",userId);
                if(roleType == RoleTypeEnum.TEACHER.getValue())
                {
                    Employee employee = employeeService.getByMapParams(paramMap);
                    if(null!=employee) {
                        userSmartDto.setSmartWxUserId(employee.getSmartUserId());
                    }
                }
                else if(roleType == RoleTypeEnum.FAMILY.getValue())
                {
                    Family family = familyService.getByMapParams(paramMap);
                    if(null!=family) {
                        userSmartDto.setSmartWxUserId(family.getSmartUserId());
                    }
                }
                return new ResultDTO<UserSmartDto>(userSmartDto);
            }
        }catch (Exception e){
            log.error("*************getCpWxUserId:{}**************", e);
        }
        return new ResultDTO<>();

    }

    @ApiOperation(value = "获取企微用户")
    @RequestMapping(value = "/getUserIdByCp", method = RequestMethod.GET)
    public ResultDTO<Long> getUserIdByCp(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "学校ID", required = true) @RequestParam(name = "corpId", required = true) String corpId,
            @ApiParam(value = "用户ID", required = true) @RequestParam(name = "cpUserId", required = true) String cpUserId){
        try{
            log.info("*************UserController-getUserIdByCp:{}**************corpId:{},cpUserId:{}",corpId,cpUserId);
            return new ResultDTO<Long>(userOpenService.getUserIdByCp(corpId,cpUserId));
        }catch (Exception e){
            log.error("*************UserController-getUserIdByCp:{}**************", e);
        }
        return new ResultDTO<>();
    }
	
	@ApiOperation(value = "获取访客用户")
    @RequestMapping(value = "/getVisitUser", method = RequestMethod.POST)
    public ResultDTO<List<UserDto>> getVisitUser(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @RequestBody List<UserDto> userList) {

        log.info("***********getVisitUser******userList:{}", userList);
        try {
            if (userList.isEmpty()) {
                return new ResultDTO(ErrorCode.PARAM_MISSING);
            }

            return new ResultDTO<List<UserDto>>(userOpenService.getVisitUser(userList));

        } catch (Exception e) {
            log.error("***********getVisitUser******", e);
            return new ResultDTO(ErrorCode.SYSTEM_EXCEPTION);
        }

    }

    @ApiOperation(value = "判断当前用户是否有身份")
    @RequestMapping(value = "/getUserRoleById", method = RequestMethod.GET)
    public ResultDTO getUserRoleById(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "学校ID", required = true) @RequestParam(name = "orgId", required = true) Long orgId,
            @ApiParam(value = "用户ID", required = true) @RequestParam(name = "userId", required = true) Long userId) {

        log.info("***********getUserRoleById******orgId:{},userId:{}", orgId, userId);
        try {
            if (null==orgId||null==userId) {
                return new ResultDTO(ErrorCode.PARAM_MISSING);
            }
            return new ResultDTO<>(userOpenService.getUserRoleById(orgId, userId));
        } catch (Exception e) {
            log.error("***********getUserRoleById******", e);
            return new ResultDTO(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    @ApiOperation(value = "获取当前用户所在学校身份集合")
    @RequestMapping(value = "/getUserRoleByOrgId", method = RequestMethod.GET)
    public ResultDTO<List<Integer>> getUserRoleByOrgId(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "学校ID", required = true) @RequestParam(name = "orgId", required = true) Long orgId,
            @ApiParam(value = "用户ID", required = true) @RequestParam(name = "userId", required = true) Long userId) {
        log.info("***********getUserRoleByOrgId******orgId:{},userId:{}", orgId, userId);
        try {
            if (null==orgId||null==userId) {
                return new ResultDTO(ErrorCode.PARAM_MISSING);
            }
            return new ResultDTO<>(userOpenService.getUserRoleByOrgId(orgId, userId));
        } catch (Exception e) {
            log.error("***********getUserRoleByOrgId******", e);
            return new ResultDTO(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    @ApiOperation(value = "获取当前用户身份并同步到XMPP")
    @RequestMapping(value = "/xmppUpdatePersonByRole", method = RequestMethod.POST)
    public ResultDTO xmppUpdatePersonByRole(
            @ApiParam(value = "接口版本", defaultValue = VersionConstant.V1, required = true) @PathVariable(name = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "组织ID", required = true) @RequestParam(value = "orgId", required = true) Long orgId,
            @ApiParam(value = "用户ID", required = true) @RequestParam(value = "userId", required = true) Long userId
    ) {
        log.info("***********XmppController.xmppUpdatePersonByRole******apiVersion:{},orgId:{},userId:{}", apiVersion, orgId, userId);
        if (null==orgId||null==userId ) {
            return new ResultDTO(ErrorCode.PARAM_MISSING);
        }
        try {
            userOpenService.xmppUpdatePersonByRole(orgId, userId);
            return new ResultDTO();
        } catch (Exception e) {
            log.error("***********XmppController.xmppUpdatePersonByRole******", e);
            return new ResultDTO(false);
        }
    }

    @ApiOperation(value = "刷新用户缓存信息")
    @RequestMapping(value = "/refreshUserRedis", method = RequestMethod.GET)
    public ResultDTO refreshUserRedis(@ApiParam(value = "接口版本", defaultValue = VersionConstant.V1, required = true) @PathVariable(name = "apiVersion", required = true) String apiVersio)
    {
        String userFrontKey = RedisKeyConstant.WKBB_BASIC_USER_FRONT + "user_accountid_*";
        List<RedisPropDto> keyList = redisTemplateUtil.queryListByKey(userFrontKey);
        log.info("refreshUserRedis数据量，size:{}",keyList.size());
        keyList.forEach(
                redisPropDto ->{
                String userTokenRedisKey = redisPropDto.getKey();
                String userJsonStr = redisTemplateUtil.getJSON(userTokenRedisKey);
                if(StringUtil.isNotEmpty(userJsonStr)) {
                    redisTemplateUtil.expire(userTokenRedisKey, RedisKeyConstant.EXPIRATION_TIME_1_YEAR, TimeUnit.SECONDS);
                }
            }
        );

        return new ResultDTO(true);
    }

    @ApiOperation(value = "根据union获取user的信息接口")
    @RequestMapping(value = "/getUserByUnion", method = RequestMethod.GET)
    public ResultDTO<UserUnionDto> getUserByUnion(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "unionId", required = true) @RequestParam(name = "unionId", required = true) String unionId) {
        log.info("***********getUserByUnion******unionId:{}", unionId);
        try {
            if (StringUtils.isEmpty(unionId)) {
                return new ResultDTO<UserUnionDto>(ErrorCode.PARAM_MISSING);
            }
            UserUnionDto userUnionDto = userOpenService.getUserByUnion(unionId);
            return new ResultDTO<UserUnionDto>(userUnionDto);
        } catch (Exception e) {
            log.error("***********getUserByUnion******", e);
            return new ResultDTO<UserUnionDto>(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    @ApiOperation(value = "获取上次登录信息")
    @RequestMapping(value = "/getUserLastLogin", method = RequestMethod.GET)
    public ResultDTO<UserLastLogin> getUserLastLogin(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "unionId", required = true) @RequestParam(name = "unionId", required = true) String unionId)
    {
        log.info("***********getUserLastLogin******unionId:{}", unionId);
        try {
            if (unionId.isEmpty()) {
                return new ResultDTO(ErrorCode.PARAM_MISSING);
            }

            Map<String, Object> params = new HashMap<>();
            params.put("type",LoginTypeEnum.MINI.getValue());
            params.put("unionId",unionId);

            return new ResultDTO<UserLastLogin>(userService.getUserLastLogin(params));

        } catch (Exception e) {
            log.error("***********getUserLastLogin******", e);
            return new ResultDTO(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    @ApiOperation(value = "设置上次登录信息")
    @RequestMapping(value = "/setUserLastLogin", method = RequestMethod.POST)
    public ResultDTO setUserLastLogin(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "公众号ID", required = false) @RequestParam(name = "accountId", required = false) Long accountId,
            @ApiParam(value = "组织ID", required = true) @RequestParam(value = "orgId", required = true) Long orgId,
            @ApiParam(value = "用户ID", required = true) @RequestParam(value = "userId", required = true) Long userId,
            @ApiParam(value = "角色类型(1教师2家长3学生4职员5游客)", required = true) @RequestParam(value = "roleType", required = true) Integer roleType,
            @ApiParam(value = "用户类型(1园长 2教师 3保育员 4 营养师 5代课教师 6职员)", required = false) @RequestParam(value = "userType", required = false) Integer userType,
            @ApiParam(value = "unionId", required = true) @RequestParam(name = "unionId", required = true) String unionId)
    {
        log.info("***********setUserLastLogin******unionId:{}", unionId);
        try {
            if (unionId.isEmpty()) {
                return new ResultDTO(ErrorCode.PARAM_MISSING);
            }

            Map<String, Object> params = new HashMap<>();
            params.put("type",LoginTypeEnum.MINI.getValue());
            params.put("unionId",unionId);

            UserLastLogin userLastLogin = userService.getUserLastLogin(params);
            if(null==userLastLogin)
            {
                userLastLogin = new UserLastLogin();
                userLastLogin.setType(LoginTypeEnum.MINI.getValue().shortValue());
                userLastLogin.setAccountId(accountId);
                userLastLogin.setOrgId(orgId);
                userLastLogin.setUserId(userId);
                userLastLogin.setRoleType(null==roleType?null:roleType.shortValue());
                userLastLogin.setUserType(null==userType?null:userType.shortValue());
                userLastLogin.setUnionId(unionId);

                userService.addUserLastLogin(userLastLogin);
            }
            else
            {
                userLastLogin.setAccountId(accountId);
                userLastLogin.setOrgId(orgId);
                userLastLogin.setUserId(userId);
                userLastLogin.setRoleType(null==roleType?null:roleType.shortValue());
                userLastLogin.setUserType(null==userType?null:userType.shortValue());

                userService.updateUserLastLogin(userLastLogin);
            }

            return new ResultDTO<UserLoginLog>(true);

        } catch (Exception e) {
            log.error("***********setUserLastLogin******", e);
            return new ResultDTO(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    @ApiOperation(value = "清除游客登录信息")
    @RequestMapping(value = "/clearVisitorLogin", method = RequestMethod.POST)
    public ResultDTO clearVisitorLogin(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "登录类型", required = true) @RequestParam(name = "type", required = true) Integer type,
            @ApiParam(value = "公众号ID", required = true) @RequestParam(name = "accountId", required = true) Long accountId,
            @ApiParam(value = "用户ID", required = true) @RequestParam(value = "userId", required = true) Long userId,
            @ApiParam(value = "unionId", required = true) @RequestParam(name = "unionId", required = true) String unionId)
    {
        log.info("***********clearVisitorLogin******unionId:{}", unionId);
        try {
            if (unionId.isEmpty()) {
                return new ResultDTO(ErrorCode.PARAM_MISSING);
            }

            boolean flag = userService.clearBindUserByAccount(accountId,unionId);
            if(flag) {
                Map<String, Object> params = new HashMap<>();
                params.put("type", type);
                params.put("accountId", accountId);
                params.put("userId", userId);
                params.put("unionId", unionId);

                userService.updateUserLastLoginStatus(params);
            }

            return new ResultDTO(flag);
        } catch (Exception e) {
            log.error("***********clearVisitorLogin******", e);
            return new ResultDTO(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    @ApiOperation(value = "清除用户登录缓存")
    @RequestMapping(value = "/clearUserLoginRedis", method = RequestMethod.POST)
    public ResultDTO clearUserLoginRedis(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "组织ID", required = true) @RequestParam(value = "orgId", required = true) Long orgId,
            @ApiParam(value = "用户ID", required = false) @RequestParam(value = "userId", required = false) Long userId,
            @ApiParam(value = "unionId", required = false) @RequestParam(name = "unionId", required = false) String unionId,
            @ApiParam(value = "是否路由模式", required = false, defaultValue = "false") @RequestParam(name = "routeFlag", required = false) Boolean routeFlag)
    {
        log.info("***********clearUserLoginRedis******orgId:{} userId:{} unionId:{}", orgId, userId, unionId);
        try {
            if (null==orgId) {
                return new ResultDTO(ErrorCode.PARAM_MISSING);
            }

           // userService.clearUserLoginRedis(routeFlag,orgId,userId,unionId);

            return new ResultDTO(true);
        } catch (Exception e) {
            log.error("***********clearUserLoginRedis******", e);
            return new ResultDTO(ErrorCode.SYSTEM_EXCEPTION);
        }
    }
}
